package com.itheima.health.service.impl;

import com.itheima.health.common.ExportExcelData;
import com.itheima.health.dao.MemberDao;
import com.itheima.health.dao.OrderDao;
import com.itheima.health.dao.OrderSettingDao;
import com.itheima.health.entity.ReservationInfo;
import com.itheima.health.exception.BusinessRuntimeException;
import com.itheima.health.pojo.Member;
import com.itheima.health.pojo.Order;
import com.itheima.health.pojo.OrderSetting;
import com.itheima.health.service.OrderService;
import com.itheima.health.vo.OrderSubmitParam;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

/**
 * 预约ServiceImpl
 */
@Service
@Slf4j
public class OrderServiceImpl implements OrderService {

    @Autowired
    private OrderSettingDao orderSettingDao;

    @Autowired
    private OrderDao orderDao;

    @Autowired
    private MemberDao memberDao;

    @Autowired
    private RedisTemplate redisTemplate;

    /**
     *  体检预约 功能
     * @param orderSubmitParam
     */
    @Override
    @Transactional
    public Order submitOrder(OrderSubmitParam orderSubmitParam) {
        Date orderDate = orderSubmitParam.getOrderDate();//预约日期
        String validateCode = orderSubmitParam.getValidateCode();//验证码
        String name = orderSubmitParam.getName();//体检人
        String idCard = orderSubmitParam.getIdCard();//身份证
        String sex = orderSubmitParam.getSex();// 性别
        Integer setMealId = orderSubmitParam.getSetMealId();//套餐id
        String telephone = orderSubmitParam.getTelephone();//手机号
        // 为 体检日期、验证码、体检人姓名 判空，为空提示输入！
        if (orderDate == null) {
            throw new BusinessRuntimeException("请选择体检日期！！！");
        }
        if (validateCode == null) {
            throw new BusinessRuntimeException("请输入验证码！！！");
        }
        if (name == null) {
            throw new BusinessRuntimeException("请输入体检人姓名！！！");
        }
        //判断验证码是否正确
        String orderValidateCode = (String) redisTemplate.opsForValue().get("ORDER_" + telephone);
        if (orderValidateCode==null){
            throw new BusinessRuntimeException("请发送验证码！！！");
        }
        if (!orderValidateCode.equals(validateCode)) {
            throw new BusinessRuntimeException("验证码错误，请重新输入！！！");
        }

        OrderSetting orderSetting = null;
        List<OrderSetting> orderSettings = orderSettingDao.selectByOrderDate(orderDate);
        //为了解决没有设置预约日期  就预约了 ，出现的错误 的问题。
        if (orderSettings.size()==0){
            throw new BusinessRuntimeException("该预约日期还没开启，联系相关人员开启 当前预约日期 的预约设置！！！");
        }
        //为了 解决  数据库中当天  设置预约日期有多个 的问题。没有的话 也提示 设置预约
        for (OrderSetting orderSetting2 : orderSettings) {
            orderSetting=orderSetting2;
        }
        log.info("date:{}", orderDate);
        //判断 当前预约 是否已满  (通过预约时间查询)
        if (orderSetting.getNumber() <= orderSetting.getReservations()) {
            throw new BusinessRuntimeException("当前日期预约人数已满，请选择其他时间进行预约！！！");
        }
        // 解决之前添加多个 手机号相同的会员信息。
        Member member = null;
        List<Member> members = memberDao.selectByPhone(telephone);//通过手机号查询
        for (Member member1 : members) {
            member=member1;
        }
        Integer memberId = null;//是老会员进if判断进行赋值，不是老会员 进else语句 进行赋值
        //判断是否是老会员
        if (member!=null) {
            memberId=member.getId();
            //1.通过会员id查询 订单预约表 返回member的list表
            List<Order>  orders = orderDao.findOrderByMemberId(memberId);
            //2.遍历list 获取预约日期 3.判断日期与当前预约日期
            for (Order order : orders) {
                if (order.getOrderDate().equals(orderDate)){
                    //如果相等抛异常 提示  已预约，不能重复预约。
                    throw new BusinessRuntimeException("今天已预约，请选择其他时间进行预约！！！");
                }
            }
            // 到这 当前日期可预约  。
        }else {
            //注册会员
            Member regMember = new Member();
            regMember.setName(name);
            regMember.setSex(sex);
            regMember.setIdCard(idCard);
            regMember.setPhoneNumber(telephone);
            Date date = new Date(System.currentTimeMillis());
            regMember.setRegTime(date);
            memberDao.save(regMember);
            memberId=regMember.getId();
        }
        //提交预约信息
        Order order = new Order();
        order.setMemberId(memberId);
        order.setOrderDate(orderDate);//设置 预约日期
        order.setOrderType("微信预约");
        order.setOrderStatus("未到诊");
        order.setSetmealId(setMealId);
        orderDao.save(order);
        //预约成功后   已预约人数  加一
        orderSetting.setReservations(orderSetting.getReservations()+1);
        orderSettingDao.updateReservations(orderSetting);
        return order;
    }

    /**
     *     预约订单数据展示
     *     自定义了一个 ReservationInfo  entity类，用于响应前端数据
     */
    @Override
    public ReservationInfo findById(String orderId) {
        String memberName = orderDao.selectMemberNameByOrderId(orderId);//查询体检人
        String setmealName = orderDao.selectSetmealNameByOrderId(orderId);//查询套餐名称
        Date orderDate = orderDao.selectDateByOrderId(orderId);//查询 预约时间
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        String format = simpleDateFormat.format(orderDate);
        String orderType = orderDao.selectOrderTypeById(orderId);//查询预约类型
        return new ReservationInfo(memberName,setmealName,format,orderType);//返回数据
    }

    /**
     * 导出excel数据
     * @return
     */
    @Override
    public List<ExportExcelData> listHotSermeal(HttpServletResponse response) throws Exception{
        List<ExportExcelData> list = orderDao.selectListHotSermeal();
        //修改数据类型
        for (ExportExcelData exportExcelData : list) {
            if (exportExcelData.getProportion().substring(2,4).startsWith("0")){
                exportExcelData.setProportion(exportExcelData.getProportion().substring(3,4)+
                        "."+exportExcelData.getProportion().substring(4)+"%");
            }else {
                exportExcelData.setProportion(exportExcelData.getProportion().substring(2,4)+
                        "."+exportExcelData.getProportion().substring(4)+"%");
            }
        }
        //获取流
        InputStream io = this.getClass().getClassLoader().getResourceAsStream("ReportTemplate.xlsx");

        XSSFWorkbook workbook = new XSSFWorkbook(io);
        OutputStream os = response.getOutputStream();
        XSSFSheet sheetAt = workbook.getSheetAt(0);
        //写入数据
        sheetAt.getRow(2).getCell(5).setCellValue(list.get(0).getTime());
        sheetAt.getRow(4).getCell(5).setCellValue(list.get(0).getDayNum());
        sheetAt.getRow(4).getCell(7).setCellValue(list.get(0).getMenberNum());
        sheetAt.getRow(5).getCell(5).setCellValue(list.get(0).getWeekNum());
        sheetAt.getRow(5).getCell(7).setCellValue(list.get(0).getMonthNum());

        sheetAt.getRow(7).getCell(5).setCellValue(list.get(0).getDay());
        sheetAt.getRow(7).getCell(7).setCellValue(list.get(0).getDayok());
        sheetAt.getRow(8).getCell(5).setCellValue(list.get(0).getWeek());
        sheetAt.getRow(8).getCell(7).setCellValue(list.get(0).getWeekok());
        sheetAt.getRow(9).getCell(5).setCellValue(list.get(0).getMonth());
        sheetAt.getRow(9).getCell(7).setCellValue(list.get(0).getMonthok());

        for (int i = 12; i <16 ; i++) {
            sheetAt.getRow(i).getCell(4).setCellValue(list.get(i-12).getName());
            sheetAt.getRow(i).getCell(5).setCellValue(list.get(i-12).getNum());
            sheetAt.getRow(i).getCell(6).setCellValue(list.get(i-12).getProportion());
            sheetAt.getRow(i).getCell(7).setCellValue(list.get(i-12).getRemark());
        }
        //设置返回
        response.setContentType("application/vnd.ms-excel");
        response.setHeader("content-Disposition","attachment;fileName=Data_Reporting.xlsx");
        workbook.write(os);

        return null;
    }

}
